<!DOCTYPE html>
<html lang="en-US">
    <head>
        <title>Data::Dump::Streamer - Accurately serialize a data structure as Perl code. - metacpan.org</title>
        <link rel="preload" as="fetch" href="https://metacpan.org/account/login_status" crossorigin="anonymous" />
        <link href="https://metacpan.org/_assets/b8ccceeed47a0652049703d99326a9cea4933443.css" rel="stylesheet" type="text/css">
        <script src="https://metacpan.org/_assets/6bfedafe2d7caa915b7d84f61b45936818e3242e.js" type="text/javascript" defer></script>
        <link rel="alternate" type="application/rss+xml" title="Recent CPAN Uploads of Data-Dump-Streamer - MetaCPAN" href="https://metacpan.org/dist/Data-Dump-Streamer/releases.rss" />
        <link rel="canonical" href="./Data::Dump::Streamer.html" />
        <meta name="description" content="Accurately serialize a data structure as Perl code." />
        <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=5">
        <link rel="shortcut icon" href="https://metacpan.org/static/icons/favicon.ico">
        <link rel="apple-touch-icon" sizes="152x152" href="https://metacpan.org/static/icons/apple-touch-icon.png">
        <link rel="search" href="https://metacpan.org/static/opensearch.xml" type="application/opensearchdescription+xml" title="MetaCPAN">
        <script>
          (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
          (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
          m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
          })(window,document,'script','//www.google-analytics.com/analytics.js','ga');

          (function(skey, ga_id){
            ga('create', ga_id, {
              siteSpeedSampleRate : 100,
              storage             : 'none',
              clientId            : localStorage.getItem(skey)
            });
            ga(function(tracker) {
              localStorage.setItem(skey, tracker.get('clientId'));
            });
            ga('send', 'pageview');
          })('ga:clientId', 'UA-27829474-1');
        </script>
<meta name="twitter:card"        content="summary" />
<meta name="twitter:url"         content="https://metacpan.org/pod/Data::Dump::Streamer" />
<meta name="twitter:title"       content="Data::Dump::Streamer" />
<meta name="twitter:description" content="Accurately serialize a data structure as Perl code." />
<meta name="twitter:site"        content="metacpan" />
    </head>
    <body>
        <nav class="navbar navbar-default" role="navigation">
            <div class="header-logo-large hidden-xs">
              <a href="https://metacpan.org/" tabindex="0">
                <svg class="logo" aria-label="MetaCPAN">
                  <use class="logo" href="/static/images/metacpan-logo.svg#logo" />
                </svg>
              </a>
            </div>
            <div class="header-logo-icon visible-xs">
              <a href="https://metacpan.org/">
                <svg class="logo" aria-label="MetaCPAN">
                  <use class="logo" href="/static/images/metacpan-logo.svg#dots" />
                </svg>
              </a>
            </div>
            <ul class="nav navbar-nav menu-items hidden-xs hidden-sm">
              <li><a href="https://metacpan.org/about">About</a></li>
              <li><a href="https://metacpan.org/about/sponsors">Sponsor</a></li>
              <li><a href="https://grep.metacpan.org/">grep::cpan</a></li>
              <li><a href="https://metacpan.org/recent">Recent</a></li>
              <li><a href="https://metacpan.org/about/faq">FAQ</a></li>
              <li><a href="https://metacpan.org/tools">Tools</a></li>
              <li><a href="https://fastapi.metacpan.org/">API</a></li>
            </ul>
            <ul class="nav navbar-nav navbar-right">
                <button type="button" class="searchbar-btn visible-xs visible-sm">
                    <i class="fa fa-search button-fa-icon"></i>
                </button>
                <form action="https://metacpan.org/search" class="searchbar-form visible-md visible-lg search-form form-horizontal">
                   <input type="hidden" name="size" id="metacpan_search-size" value="20">
                  <div class="form-group">
                      <div class="search-group">
                        <i class="fa fa-search"></i>
                        <input type="text" name="q" placeholder="Search the CPAN" size="41" autocorrect="off" autocapitalize="off" spellcheck="false" id="metacpan_search-input" class="form-control" value="">
                      </div>
                  </div>
                </form>
                    <li class="icon-slidepanel visible-xs visible-sm">
                      <button data-toggle="slidepanel" data-target=".slidepanel">
                        <span class="button-fa-icon">
                          <i class="fa fa-bars slidepanel-open"></i>
                          <i class="fa fa-times slidepanel-close"></i>
                        </span>
                      </button>
                    </li>
                <form action="https://metacpan.org/account/logout" method="POST" id="metacpan-logout"></form>
                <li class="dropdown logged_in" style="display: none;">
                    <button type="button" class="dropdown-toggle" data-toggle="dropdown">
                      <i class="fa fa-user button-fa-icon logged-in-icon" aria-hidden="true"></i>
                      <i class="fas fa-chevron-down"></i>
                    </button>
                    <ul class="dropdown-menu">
                        <li><a href="https://metacpan.org/account/identities">Identities</a></li>
                        <li><a href="https://metacpan.org/account/profile">Profile</a></li>
                        <li><a href="https://metacpan.org/account/favorite/list">Favorites</a></li>
                        <li>
                            <a href="./Data::Dump::Streamer.html#" type="button" onclick="$('#metacpan-logout').submit(); return false">
                              Logout
                            </a>
                        </li>
                    </ul>
                </li>
                <li class="dropdown logged_out" style="display: none;">
                    <button type="button" class="dropdown-toggle" data-toggle="dropdown">
                      <i class="fa fa-user button-fa-icon" aria-hidden="true"></i>
                      <i class="fas fa-chevron-down"></i>
                    </button>
                    <ul class="dropdown-menu">
                        <li>
                            <a href="https://metacpan.org/login/github">
                                <i class="fab fa-github fa-fw"></i>
                                GitHub
                            </a>
                        </li>
                        <li>
                            <a href="https://metacpan.org/login/twitter">
                                <i class="fab fa-twitter fa-fw"></i>
                                Twitter
                            </a>
                        </li>
                        <li>
                            <a href="https://metacpan.org/login/google">
                                <i class="fab fa-google fa-fw"></i>
                                Google
                            </a>
                        </li>
                    </ul>
                </li>
                <li class="dropdown logged_placeholder">
                    <button>
                      <i class="fa fa-user button-fa-icon" aria-hidden="true"></i>
                    </button>
                </li>
            </ul>
        </nav>
        <div class="page-content ">
          <!--
          <div class="top-notify-banner">
            <i class="fas fa-info-circle"></i>
          </div>
          -->
          <nav class="sidebar">
            <div class="slidepanel">
              <ul class="nav-list ">
    <li class="nav-header no-margin-top">
      <div class="ttip" data-toggle="tooltip" data-placement="bottom" title="The date that this version of Data-Dump-Streamer was released.">
      <span class="relatize">21 Feb 2023 03:08:06 UTC</span>
    </li>
  <li>
    Distribution: <a href="https://metacpan.org/dist/Data-Dump-Streamer">Data-Dump-Streamer</a>
  </li>
  <li>
    Module version: 2.42
  </li>
  <li>
    <a data-keyboard-shortcut="g s" href="https://metacpan.org/dist/Data-Dump-Streamer/source/lib/Data/Dump/Streamer.pm">Source</a>
    (<a href="https://metacpan.org/dist/Data-Dump-Streamer/source/lib/Data/Dump/Streamer.pm?raw=1">raw</a>)
  </li>
  <li>
    <a data-keyboard-shortcut="g b" href="https://metacpan.org/dist/Data-Dump-Streamer/source/lib/Data/Dump">Browse</a>
    (<a href="https://metacpan.org/dist/Data-Dump-Streamer/source/lib/Data/Dump?raw=1">raw</a>)
  </li>
    <li>
      <a data-keyboard-shortcut="g c" href="https://metacpan.org/dist/Data-Dump-Streamer/changes">Changes</a>
    </li>
    <li>
      <a class="nopopup" href="https://metacpan.org/dist/Data-Dump-Streamer/contribute">How to Contribute</a>
    </li>
    <li>
        <a rel="noopener nofollow" data-keyboard-shortcut="g r" href="https://github.com/demerphq/Data-Dump-Streamer">Repository</a>
    </li>
    <li>
      <a rel="noopener nofollow" data-keyboard-shortcut="g i" href="https://rt.cpan.org/Public/Dist/Display.html?Name=Data-Dump-Streamer">Issues</a>
      (20)
    </li>
    <li>
      <a rel="noopener nofollow" href="http://matrix.cpantesters.org/?dist=Data-Dump-Streamer+2.42" title="Matrix">Testers</a>
        <span title="(pass / fail / na)">(<a rel="noopener nofollow" href="https://www.cpantesters.org/distro/D/Data-Dump-Streamer.html?oncpan=1&amp;distmat=1&amp;version=2.42&amp;grade=2" style="color: #090">259</a> / <a rel="noopener nofollow" href="https://www.cpantesters.org/distro/D/Data-Dump-Streamer.html?oncpan=1&amp;distmat=1&amp;version=2.42&amp;grade=3" style="color: #900">0</a> / <a rel="noopener nofollow" href="https://www.cpantesters.org/distro/D/Data-Dump-Streamer.html?oncpan=1&amp;distmat=1&amp;version=2.42&amp;grade=4">0</a>)</span>
    </li>
    <li>
      <a rel="noopener nofollow" href="http://cpants.cpanauthors.org/release/YVES/Data-Dump-Streamer-2.42">Kwalitee</a>
    </li>
    <li>
      <div class="ttip" data-toggle="tooltip" data-placement="bottom" title="The # people with an indexing permission on Data-Dump-Streamer who have released something to CPAN in the last 2 years (i.e. the # people likely able to release critical fixes in a timely manner)">
      Bus factor: 1
      </div>
    </li>
    <li>
      <a rel="noopener nofollow" href="http://cpancover.com/latest/Data-Dump-Streamer-2.42/index.html">71.46% Coverage </a>
    </li>
    <li>
      License: perl_5
    </li>
    <li class="nav-header">Activity</li>
    <li>
<div class="activity-graph">
    <img src="https://metacpan.org/dist/Data-Dump-Streamer/activity.svg?res=month" />
    <div class="comment">24 month</div>
</div>
    </li>
    <li class="nav-header">Tools</li>
    <li>
      <a itemprop="downloadUrl" href="https://cpan.metacpan.org/authors/id/Y/YV/YVES/Data-Dump-Streamer-2.42.tar.gz">
      Download (<span itemprop="fileSize">144.01KB</span>)</a>
    </li>
    <li>
      <a href="https://explorer.metacpan.org/?url=%2Fmodule%2FYVES%2FData-Dump-Streamer-2.42%2Flib%2FData%2FDump%2FStreamer.pm">
        MetaCPAN Explorer
      </a>
    </li>
    <li>
      <a href="https://metacpan.org/dist/Data-Dump-Streamer/permissions">
        Permissions
      </a>
    </li>
    <li>
      <a href="https://metacpan.org/dist/Data-Dump-Streamer/releases.rss">
        Subscribe to distribution
      </a>
    </li>
    <li>
      <button class="btn btn-link" data-toggle="modal" data-target="#metacpan_install-instructions-dialog">
        Install Instructions
      </button>
    </li>
    <li>
      <form action="https://metacpan.org/search">
        <input type="hidden" name="q" value="dist:Data-Dump-Streamer">
        <input type="search" name="q" placeholder="Search distribution" class="form-control tool-bar-form">
        <input type="submit" style="display: none">
      </form>
    </li>
    <li>
      <form action="https://grep.metacpan.org/search">
        <input type="hidden" name="qd" value="Data-Dump-Streamer">
        <input type="hidden" name="source" value="metacpan">
        <input type="search" name="q" placeholder="grep distribution" class="form-control tool-bar-form">
        <input type="submit" style="display: none">
     </form>
    </li>
    <li class="version-jump">
<select onchange="document.location.href=&#39;/release/&#39;+this.value+&#39;/view/lib/Data/Dump/Streamer.pm&#39;" class="form-control tool-bar-form">
  <option disabled selected>Jump to version</option>
<option
  disabled
  value="YVES/Data-Dump-Streamer-2.42"
>2.42
  (YVES on 2023-02-21)</option>
<option
  
  value="YVES/Data-Dump-Streamer-2.41"
>2.41
  (YVES on 2023-01-27)</option>
<option
  
  value="YVES/Data-Dump-Streamer-2.40"
>2.40
  (YVES on 2016-08-30)</option>
<option
  
  value="YVES/Data-Dump-Streamer-2.39"
>2.39
  (YVES on 2015-12-24)</option>
<option
  
  value="YVES/Data-Dump-Streamer-2.38"
>2.38
  (YVES on 2014-06-12)</option>
<option
  
  value="YVES/Data-Dump-Streamer-2.37_02"
>2.37_02 DEV
  (YVES on 2014-06-11)</option>
<option
  
  value="YVES/Data-Dump-Streamer-2.37_01"
>2.37_01 DEV
  (YVES on 2014-05-19)</option>
<option
  
  value="YVES/Data-Dump-Streamer-2.37"
>2.37
  (YVES on 2014-01-30)</option>
<option
  
  value="YVES/Data-Dump-Streamer-2.36"
>2.36
  (YVES on 2013-08-07)</option>
<option
  
  value="YVES/Data-Dump-Streamer-2.34"
>2.34
  (YVES on 2012-06-06)</option>
<option
  
  value="YVES/Data-Dump-Streamer-2.33"
>2.33
  (YVES on 2012-04-01)</option>
<option
  
  value="JJORE/Data-Dump-Streamer-2.32"
>2.32
  (JJORE on 2011-02-05)</option>
<option
  
  value="YVES/Data-Dump-Streamer-2.09"
>2.09
  (YVES on 2009-03-24)</option>
<option
  
  value="YVES/Data-Dump-Streamer-2.08-40"
>2.08-40
  (YVES on 2007-12-22)</option>
<option
  
  value="YVES/Data-Dump-Streamer-2.07-39"
>2.07-39
  (YVES on 2007-12-22)</option>
<option
  
  value="YVES/Data-Dump-Streamer-2.06-38"
>2.06-38
  (YVES on 2007-12-21)</option>
<option
  
  value="YVES/Data-Dump-Streamer-2.05-36"
>2.05-36
  (YVES on 2007-08-22)</option>
<option
  
  value="YVES/Data-Dump-Streamer-2.04-34"
>2.04-34
  (YVES on 2007-08-22)</option>
<option
  
  value="YVES/Data-Dump-Streamer-2.03-30"
>2.03-30
  (YVES on 2006-04-16)</option>
<option
  
  value="YVES/Data-Dump-Streamer-2.02"
>2.02
  (YVES on 2006-03-19)</option>
<option
  
  value="YVES/Data-Dump-Streamer-2.01"
>2.01
  (YVES on 2006-03-18)</option>
<option
  
  value="YVES/Data-Dump-Streamer-2.00"
>2.00
  (YVES on 2006-03-16)</option>
<option
  
  value="YVES/Data-Dump-Streamer-1.14"
>1.14
  (YVES on 2005-06-27)</option>
<option
  
  value="YVES/Data-Dump-Streamer-1.12"
>1.12
  (YVES on 2005-05-26)</option>
<option
  
  value="YVES/Data-Dump-Streamer-1.11"
>1.11
  (YVES on 2005-05-23)</option>
<optgroup label="BackPAN">'
<option
  
  value="JJORE/Data-Dump-Streamer-2.31"
>2.31
  (JJORE on 2011-02-02)</option>
<option
  
  value="JJORE/Data-Dump-Streamer-2.29"
>2.29
  (JJORE on 2011-02-02)</option>
<option
  
  value="JJORE/Data-Dump-Streamer-2.28"
>2.28
  (JJORE on 2011-02-01)</option>
<option
  
  value="JJORE/Data-Dump-Streamer-2.27"
>2.27
  (JJORE on 2011-02-01)</option>
<option
  
  value="JJORE/Data-Dump-Streamer-2.26"
>2.26
  (JJORE on 2011-02-01)</option>
<option
  
  value="JJORE/Data-Dump-Streamer-2.25"
>2.25
  (JJORE on 2011-01-24)</option>
<option
  
  value="JJORE/Data-Dump-Streamer-2.24"
>2.24
  (JJORE on 2011-01-24)</option>
<option
  
  value="JJORE/Data-Dump-Streamer-2.23"
>2.23
  (JJORE on 2011-01-19)</option>
<option
  
  value="JJORE/Data-Dump-Streamer-2.22"
>2.22
  (JJORE on 2010-07-12)</option>
<option
  
  value="JJORE/Data-Dump-Streamer-2.21"
>2.21
  (JJORE on 2010-06-19)</option>
<option
  
  value="JJORE/Data-Dump-Streamer-2.19"
>2.19
  (JJORE on 2010-06-19)</option>
<option
  
  value="JJORE/Data-Dump-Streamer-2.18"
>2.18
  (JJORE on 2010-06-12)</option>
<option
  
  value="JJORE/Data-Dump-Streamer-2.17"
>2.17
  (JJORE on 2010-06-11)</option>
<option
  
  value="JJORE/Data-Dump-Streamer-2.16"
>2.16
  (JJORE on 2010-06-11)</option>
<option
  
  value="JJORE/Data-Dump-Streamer-2.15"
>2.15
  (JJORE on 2010-06-11)</option>
<option
  
  value="JJORE/Data-Dump-Streamer-2.14"
>2.14
  (JJORE on 2010-06-08)</option>
<option
  
  value="JJORE/Data-Dump-Streamer-2.13"
>2.13
  (JJORE on 2010-04-05)</option>
<option
  
  value="JJORE/Data-Dump-Streamer-2.12"
>2.12
  (JJORE on 2010-04-05)</option>
<option
  
  value="JJORE/Data-Dump-Streamer-2.11"
>2.11
  (JJORE on 2010-04-04)</option>
<option
  
  value="JJORE/Data-Dump-Streamer-2.10"
>2.10
  (JJORE on 2010-04-04)</option>
<option
  
  value="YVES/Data-Dump-Streamer-1.10"
>1.10
  (YVES on 2004-05-02)</option>
<option
  
  value="YVES/Data-Dump-Streamer-1.09"
>1.09
  (YVES on 2004-05-01)</option>
<option
  
  value="YVES/Data-Dump-Streamer-1.08"
>1.08
  (YVES on 2004-04-30)</option>
<option
  
  value="YVES/Data-Dump-Streamer-1.07"
>1.07
  (YVES on 2004-04-30)</option>
<option
  
  value="YVES/Data-Dump-Streamer-1.06"
>1.06
  (YVES on 2004-03-23)</option>
<option
  
  value="YVES/Data-Dump-Streamer-1.05"
>1.05
  (YVES on 2004-03-14)</option>
<option
  
  value="YVES/Data-Dump-Streamer-1.04"
>1.04
  (YVES on 2004-03-01)</option>
<option
  
  value="YVES/Data-Dump-Streamer-1.03"
>1.03
  (YVES on 2004-02-28)</option>
<option
  
  value="YVES/Data-Dump-Streamer-1.02"
>1.02
  (YVES on 2004-02-26)</option>
<option
  
  value="YVES/Data-Dump-Streamer-1.01"
>1.01
  (YVES on 2004-02-24)</option>
<option
  
  value="YVES/Data-Dump-Streamer-1.0"
>1.0
  (YVES on 2004-02-23)</option>
</optgroup>
</select>
    </li>
    <li class="version-diff">
<select onchange="document.location.href='/release/YVES/Data-Dump-Streamer-2.42/diff/' + encodeURIComponent(this.value) + '/lib/Data/Dump/Streamer.pm'
" class="form-control tool-bar-form">
  <option disabled selected>Diff with version</option>
<option
  disabled
  value="YVES/Data-Dump-Streamer-2.42"
>2.42
  (YVES on 2023-02-21)</option>
<option
  
  value="YVES/Data-Dump-Streamer-2.41"
>2.41
  (YVES on 2023-01-27)</option>
<option
  
  value="YVES/Data-Dump-Streamer-2.40"
>2.40
  (YVES on 2016-08-30)</option>
<option
  
  value="YVES/Data-Dump-Streamer-2.39"
>2.39
  (YVES on 2015-12-24)</option>
<option
  
  value="YVES/Data-Dump-Streamer-2.38"
>2.38
  (YVES on 2014-06-12)</option>
<option
  
  value="YVES/Data-Dump-Streamer-2.37_02"
>2.37_02 DEV
  (YVES on 2014-06-11)</option>
<option
  
  value="YVES/Data-Dump-Streamer-2.37_01"
>2.37_01 DEV
  (YVES on 2014-05-19)</option>
<option
  
  value="YVES/Data-Dump-Streamer-2.37"
>2.37
  (YVES on 2014-01-30)</option>
<option
  
  value="YVES/Data-Dump-Streamer-2.36"
>2.36
  (YVES on 2013-08-07)</option>
<option
  
  value="YVES/Data-Dump-Streamer-2.34"
>2.34
  (YVES on 2012-06-06)</option>
<option
  
  value="YVES/Data-Dump-Streamer-2.33"
>2.33
  (YVES on 2012-04-01)</option>
<option
  
  value="JJORE/Data-Dump-Streamer-2.32"
>2.32
  (JJORE on 2011-02-05)</option>
<option
  
  value="YVES/Data-Dump-Streamer-2.09"
>2.09
  (YVES on 2009-03-24)</option>
<option
  
  value="YVES/Data-Dump-Streamer-2.08-40"
>2.08-40
  (YVES on 2007-12-22)</option>
<option
  
  value="YVES/Data-Dump-Streamer-2.07-39"
>2.07-39
  (YVES on 2007-12-22)</option>
<option
  
  value="YVES/Data-Dump-Streamer-2.06-38"
>2.06-38
  (YVES on 2007-12-21)</option>
<option
  
  value="YVES/Data-Dump-Streamer-2.05-36"
>2.05-36
  (YVES on 2007-08-22)</option>
<option
  
  value="YVES/Data-Dump-Streamer-2.04-34"
>2.04-34
  (YVES on 2007-08-22)</option>
<option
  
  value="YVES/Data-Dump-Streamer-2.03-30"
>2.03-30
  (YVES on 2006-04-16)</option>
<option
  
  value="YVES/Data-Dump-Streamer-2.02"
>2.02
  (YVES on 2006-03-19)</option>
<option
  
  value="YVES/Data-Dump-Streamer-2.01"
>2.01
  (YVES on 2006-03-18)</option>
<option
  
  value="YVES/Data-Dump-Streamer-2.00"
>2.00
  (YVES on 2006-03-16)</option>
<option
  
  value="YVES/Data-Dump-Streamer-1.14"
>1.14
  (YVES on 2005-06-27)</option>
<option
  
  value="YVES/Data-Dump-Streamer-1.12"
>1.12
  (YVES on 2005-05-26)</option>
<option
  
  value="YVES/Data-Dump-Streamer-1.11"
>1.11
  (YVES on 2005-05-23)</option>
<optgroup label="BackPAN">'
<option
  
  value="JJORE/Data-Dump-Streamer-2.31"
>2.31
  (JJORE on 2011-02-02)</option>
<option
  
  value="JJORE/Data-Dump-Streamer-2.29"
>2.29
  (JJORE on 2011-02-02)</option>
<option
  
  value="JJORE/Data-Dump-Streamer-2.28"
>2.28
  (JJORE on 2011-02-01)</option>
<option
  
  value="JJORE/Data-Dump-Streamer-2.27"
>2.27
  (JJORE on 2011-02-01)</option>
<option
  
  value="JJORE/Data-Dump-Streamer-2.26"
>2.26
  (JJORE on 2011-02-01)</option>
<option
  
  value="JJORE/Data-Dump-Streamer-2.25"
>2.25
  (JJORE on 2011-01-24)</option>
<option
  
  value="JJORE/Data-Dump-Streamer-2.24"
>2.24
  (JJORE on 2011-01-24)</option>
<option
  
  value="JJORE/Data-Dump-Streamer-2.23"
>2.23
  (JJORE on 2011-01-19)</option>
<option
  
  value="JJORE/Data-Dump-Streamer-2.22"
>2.22
  (JJORE on 2010-07-12)</option>
<option
  
  value="JJORE/Data-Dump-Streamer-2.21"
>2.21
  (JJORE on 2010-06-19)</option>
<option
  
  value="JJORE/Data-Dump-Streamer-2.19"
>2.19
  (JJORE on 2010-06-19)</option>
<option
  
  value="JJORE/Data-Dump-Streamer-2.18"
>2.18
  (JJORE on 2010-06-12)</option>
<option
  
  value="JJORE/Data-Dump-Streamer-2.17"
>2.17
  (JJORE on 2010-06-11)</option>
<option
  
  value="JJORE/Data-Dump-Streamer-2.16"
>2.16
  (JJORE on 2010-06-11)</option>
<option
  
  value="JJORE/Data-Dump-Streamer-2.15"
>2.15
  (JJORE on 2010-06-11)</option>
<option
  
  value="JJORE/Data-Dump-Streamer-2.14"
>2.14
  (JJORE on 2010-06-08)</option>
<option
  
  value="JJORE/Data-Dump-Streamer-2.13"
>2.13
  (JJORE on 2010-04-05)</option>
<option
  
  value="JJORE/Data-Dump-Streamer-2.12"
>2.12
  (JJORE on 2010-04-05)</option>
<option
  
  value="JJORE/Data-Dump-Streamer-2.11"
>2.11
  (JJORE on 2010-04-04)</option>
<option
  
  value="JJORE/Data-Dump-Streamer-2.10"
>2.10
  (JJORE on 2010-04-04)</option>
<option
  
  value="YVES/Data-Dump-Streamer-1.10"
>1.10
  (YVES on 2004-05-02)</option>
<option
  
  value="YVES/Data-Dump-Streamer-1.09"
>1.09
  (YVES on 2004-05-01)</option>
<option
  
  value="YVES/Data-Dump-Streamer-1.08"
>1.08
  (YVES on 2004-04-30)</option>
<option
  
  value="YVES/Data-Dump-Streamer-1.07"
>1.07
  (YVES on 2004-04-30)</option>
<option
  
  value="YVES/Data-Dump-Streamer-1.06"
>1.06
  (YVES on 2004-03-23)</option>
<option
  
  value="YVES/Data-Dump-Streamer-1.05"
>1.05
  (YVES on 2004-03-14)</option>
<option
  
  value="YVES/Data-Dump-Streamer-1.04"
>1.04
  (YVES on 2004-03-01)</option>
<option
  
  value="YVES/Data-Dump-Streamer-1.03"
>1.03
  (YVES on 2004-02-28)</option>
<option
  
  value="YVES/Data-Dump-Streamer-1.02"
>1.02
  (YVES on 2004-02-26)</option>
<option
  
  value="YVES/Data-Dump-Streamer-1.01"
>1.01
  (YVES on 2004-02-24)</option>
<option
  
  value="YVES/Data-Dump-Streamer-1.0"
>1.0
  (YVES on 2004-02-23)</option>
</optgroup>
</select>
    </li>

    <li>
<ul class="dependencies">
  <li class="nav-header">Dependencies</li>
  <li><a href="https://metacpan.org/pod/B" title="B" class="ellipsis">B</a></li>
  <li><a href="https://metacpan.org/pod/B::Deparse" title="B::Deparse" class="ellipsis">B::Deparse</a></li>
  <li><a href="./B::Utils.html" title="B::Utils" class="ellipsis">B::Utils</a></li>
  <li><a href="https://metacpan.org/pod/Data::Dumper" title="Data::Dumper" class="ellipsis">Data::Dumper</a></li>
  <li><a href="https://metacpan.org/pod/DynaLoader" title="DynaLoader" class="ellipsis">DynaLoader</a></li>
  <li><a href="https://metacpan.org/pod/Exporter" title="Exporter" class="ellipsis">Exporter</a></li>
  <li><a href="https://metacpan.org/pod/Hash::Util" title="Hash::Util" class="ellipsis">Hash::Util</a></li>
  <li><a href="https://metacpan.org/pod/IO::File" title="IO::File" class="ellipsis">IO::File</a></li>
  <li><a href="https://metacpan.org/pod/Symbol" title="Symbol" class="ellipsis">Symbol</a></li>
  <li><a href="https://metacpan.org/pod/Text::Abbrev" title="Text::Abbrev" class="ellipsis">Text::Abbrev</a></li>
  <li><a href="https://metacpan.org/pod/Text::Balanced" title="Text::Balanced" class="ellipsis">Text::Balanced</a></li>
  <li><a href="https://metacpan.org/pod/overload" title="overload" class="ellipsis">overload</a></li>
  <li><a href="https://metacpan.org/pod/re" title="re" class="ellipsis">re</a></li>
  <li><a href="https://metacpan.org/pod/strict" title="strict" class="ellipsis">strict</a></li>
  <li><a href="https://metacpan.org/pod/vars" title="vars" class="ellipsis">vars</a></li>
  <li><a href="https://metacpan.org/pod/warnings" title="warnings" class="ellipsis">warnings</a></li>
  <li><a href="https://metacpan.org/pod/warnings::register" title="warnings::register" class="ellipsis">warnings::register</a></li>
  <li><i class="ttip" title="dynamic_config enabled">and possibly others</i></li>
  <li>
    <hr>
  </li>
  <li>
    <a href="https://metacpan.org/module/Data::Dump::Streamer/requires">Reverse dependencies</a>
  </li>
  <li>
    <a href="http://deps.cpantesters.org/?module=Data%3A%3ADump%3A%3AStreamer">CPAN Testers List</a>
  </li>
  <li>
    <a href="https://cpandeps.grinnz.com/?dist=Data-Dump-Streamer">Dependency graph</a>
  </li>
</ul>
    </li>
    <li class="nav-header">Permalinks</li>
    <li>
      <a href="https://metacpan.org/release/YVES/Data-Dump-Streamer-2.42/view/lib/Data/Dump/Streamer.pm">This version</a>
    </li>
    <li>
      <a href="./Data::Dump::Streamer.html">Latest version</a>
    </li>
    <li>
<div class="plussers">
<div class="nav-header">++ed by:</div>
<div>
<a class="display-all" href="https://metacpan.org/author/PABLROD"><img src="https://www.gravatar.com/avatar/ebde00b92598043f6cf8d9071e7d5c2b?d=identicon&amp;s=20" title="PABLROD" alt="PABLROD"></a>
<a class="display-all" href="https://metacpan.org/author/ADAMJS"><img src="https://www.gravatar.com/avatar/62c7b6e864d6509cff5839543c676614?d=identicon&amp;s=20" title="ADAMJS" alt="ADAMJS"></a>
<a class="display-all" href="https://metacpan.org/author/SARTAK"><img src="https://www.gravatar.com/avatar/b0805b622209805fd673107d0fb3c707?d=identicon&amp;s=20" title="SARTAK" alt="SARTAK"></a>
<a class="display-all" href="https://metacpan.org/author/RSCHABER"><img src="https://www.gravatar.com/avatar/8735b8d5583ee0a0155a41f993cab4f3?d=identicon&amp;s=20" title="RSCHABER" alt="RSCHABER"></a>
<a class="display-all" href="https://metacpan.org/author/KRAUTCAT"><img src="https://www.gravatar.com/avatar/efd137d1577aa9df7fc833f6306958d5?d=identicon&amp;s=20" title="KRAUTCAT" alt="KRAUTCAT"></a>
</div>
<!-- Display counts of plussers-->
<div>
    <a href="https://metacpan.org/dist/Data-Dump-Streamer/plussers">6 PAUSE users</a>
</div>
<div>
    4 non-PAUSE users
</div>
</div>
    </li>
    <li>
    </li>
              </ul>
            </div>
          </nav>
          <div class="content-navigation">
<div class="breadcrumbs">
  <span>
    <a data-keyboard-shortcut="g a" rel="author" href="https://metacpan.org/author/YVES" class="author-name">Yves</a>
  </span>
  <span>&nbsp;/&nbsp;</span>
  <div class="release dist-release status-latest maturity-released">
    <span class="dropdown"><b class="caret"></b></span>
<select onchange="document.location.href=&#39;/release/&#39;+this.value+&#39;/view/lib/Data/Dump/Streamer.pm&#39;" class="">
<option
  selected
  value="YVES/Data-Dump-Streamer-2.42"
>2.42
  (YVES on 2023-02-21)</option>
<option
  
  value="YVES/Data-Dump-Streamer-2.41"
>2.41
  (YVES on 2023-01-27)</option>
<option
  
  value="YVES/Data-Dump-Streamer-2.40"
>2.40
  (YVES on 2016-08-30)</option>
<option
  
  value="YVES/Data-Dump-Streamer-2.39"
>2.39
  (YVES on 2015-12-24)</option>
<option
  
  value="YVES/Data-Dump-Streamer-2.38"
>2.38
  (YVES on 2014-06-12)</option>
<option
  
  value="YVES/Data-Dump-Streamer-2.37_02"
>2.37_02 DEV
  (YVES on 2014-06-11)</option>
<option
  
  value="YVES/Data-Dump-Streamer-2.37_01"
>2.37_01 DEV
  (YVES on 2014-05-19)</option>
<option
  
  value="YVES/Data-Dump-Streamer-2.37"
>2.37
  (YVES on 2014-01-30)</option>
<option
  
  value="YVES/Data-Dump-Streamer-2.36"
>2.36
  (YVES on 2013-08-07)</option>
<option
  
  value="YVES/Data-Dump-Streamer-2.34"
>2.34
  (YVES on 2012-06-06)</option>
<option
  
  value="YVES/Data-Dump-Streamer-2.33"
>2.33
  (YVES on 2012-04-01)</option>
<option
  
  value="JJORE/Data-Dump-Streamer-2.32"
>2.32
  (JJORE on 2011-02-05)</option>
<option
  
  value="YVES/Data-Dump-Streamer-2.09"
>2.09
  (YVES on 2009-03-24)</option>
<option
  
  value="YVES/Data-Dump-Streamer-2.08-40"
>2.08-40
  (YVES on 2007-12-22)</option>
<option
  
  value="YVES/Data-Dump-Streamer-2.07-39"
>2.07-39
  (YVES on 2007-12-22)</option>
<option
  
  value="YVES/Data-Dump-Streamer-2.06-38"
>2.06-38
  (YVES on 2007-12-21)</option>
<option
  
  value="YVES/Data-Dump-Streamer-2.05-36"
>2.05-36
  (YVES on 2007-08-22)</option>
<option
  
  value="YVES/Data-Dump-Streamer-2.04-34"
>2.04-34
  (YVES on 2007-08-22)</option>
<option
  
  value="YVES/Data-Dump-Streamer-2.03-30"
>2.03-30
  (YVES on 2006-04-16)</option>
<option
  
  value="YVES/Data-Dump-Streamer-2.02"
>2.02
  (YVES on 2006-03-19)</option>
<option
  
  value="YVES/Data-Dump-Streamer-2.01"
>2.01
  (YVES on 2006-03-18)</option>
<option
  
  value="YVES/Data-Dump-Streamer-2.00"
>2.00
  (YVES on 2006-03-16)</option>
<option
  
  value="YVES/Data-Dump-Streamer-1.14"
>1.14
  (YVES on 2005-06-27)</option>
<option
  
  value="YVES/Data-Dump-Streamer-1.12"
>1.12
  (YVES on 2005-05-26)</option>
<option
  
  value="YVES/Data-Dump-Streamer-1.11"
>1.11
  (YVES on 2005-05-23)</option>
<optgroup label="BackPAN">'
<option
  
  value="JJORE/Data-Dump-Streamer-2.31"
>2.31
  (JJORE on 2011-02-02)</option>
<option
  
  value="JJORE/Data-Dump-Streamer-2.29"
>2.29
  (JJORE on 2011-02-02)</option>
<option
  
  value="JJORE/Data-Dump-Streamer-2.28"
>2.28
  (JJORE on 2011-02-01)</option>
<option
  
  value="JJORE/Data-Dump-Streamer-2.27"
>2.27
  (JJORE on 2011-02-01)</option>
<option
  
  value="JJORE/Data-Dump-Streamer-2.26"
>2.26
  (JJORE on 2011-02-01)</option>
<option
  
  value="JJORE/Data-Dump-Streamer-2.25"
>2.25
  (JJORE on 2011-01-24)</option>
<option
  
  value="JJORE/Data-Dump-Streamer-2.24"
>2.24
  (JJORE on 2011-01-24)</option>
<option
  
  value="JJORE/Data-Dump-Streamer-2.23"
>2.23
  (JJORE on 2011-01-19)</option>
<option
  
  value="JJORE/Data-Dump-Streamer-2.22"
>2.22
  (JJORE on 2010-07-12)</option>
<option
  
  value="JJORE/Data-Dump-Streamer-2.21"
>2.21
  (JJORE on 2010-06-19)</option>
<option
  
  value="JJORE/Data-Dump-Streamer-2.19"
>2.19
  (JJORE on 2010-06-19)</option>
<option
  
  value="JJORE/Data-Dump-Streamer-2.18"
>2.18
  (JJORE on 2010-06-12)</option>
<option
  
  value="JJORE/Data-Dump-Streamer-2.17"
>2.17
  (JJORE on 2010-06-11)</option>
<option
  
  value="JJORE/Data-Dump-Streamer-2.16"
>2.16
  (JJORE on 2010-06-11)</option>
<option
  
  value="JJORE/Data-Dump-Streamer-2.15"
>2.15
  (JJORE on 2010-06-11)</option>
<option
  
  value="JJORE/Data-Dump-Streamer-2.14"
>2.14
  (JJORE on 2010-06-08)</option>
<option
  
  value="JJORE/Data-Dump-Streamer-2.13"
>2.13
  (JJORE on 2010-04-05)</option>
<option
  
  value="JJORE/Data-Dump-Streamer-2.12"
>2.12
  (JJORE on 2010-04-05)</option>
<option
  
  value="JJORE/Data-Dump-Streamer-2.11"
>2.11
  (JJORE on 2010-04-04)</option>
<option
  
  value="JJORE/Data-Dump-Streamer-2.10"
>2.10
  (JJORE on 2010-04-04)</option>
<option
  
  value="YVES/Data-Dump-Streamer-1.10"
>1.10
  (YVES on 2004-05-02)</option>
<option
  
  value="YVES/Data-Dump-Streamer-1.09"
>1.09
  (YVES on 2004-05-01)</option>
<option
  
  value="YVES/Data-Dump-Streamer-1.08"
>1.08
  (YVES on 2004-04-30)</option>
<option
  
  value="YVES/Data-Dump-Streamer-1.07"
>1.07
  (YVES on 2004-04-30)</option>
<option
  
  value="YVES/Data-Dump-Streamer-1.06"
>1.06
  (YVES on 2004-03-23)</option>
<option
  
  value="YVES/Data-Dump-Streamer-1.05"
>1.05
  (YVES on 2004-03-14)</option>
<option
  
  value="YVES/Data-Dump-Streamer-1.04"
>1.04
  (YVES on 2004-03-01)</option>
<option
  
  value="YVES/Data-Dump-Streamer-1.03"
>1.03
  (YVES on 2004-02-28)</option>
<option
  
  value="YVES/Data-Dump-Streamer-1.02"
>1.02
  (YVES on 2004-02-26)</option>
<option
  
  value="YVES/Data-Dump-Streamer-1.01"
>1.01
  (YVES on 2004-02-24)</option>
<option
  
  value="YVES/Data-Dump-Streamer-1.0"
>1.0
  (YVES on 2004-02-23)</option>
</optgroup>
</select>
    <a data-keyboard-shortcut="g d" class="release-name" href="https://metacpan.org/dist/Data-Dump-Streamer">Data-Dump-Streamer-2.42</a>
  </div>
<span class="river-gauge-gauge">
  <svg width="24px"
       height="15px"
       version="1.1"
       xmlns="http://www.w3.org/2000/svg"
       xmlns:xlink="http://www.w3.org/1999/xlink">

    <g>
      <title>        River stage two &#10;
          • 22 direct dependents &#10;          • 90 total dependents
      </title>

      <rect x="0"  y="0" width="4" height="15" fill="#7ea3f2" />
      <rect x="5"  y="0" width="4" height="15" fill="#7ea3f2" />
      <rect x="10"  y="0" width="4" height="15" fill="#e4e2e2" />
      <rect x="15"  y="0" width="4" height="15" fill="#e4e2e2" />
      <rect x="20"  y="0" width="4" height="15" fill="#e4e2e2" />
    </g>
  </svg>

</span>
<div id="Data-Dump-Streamer-fav" class="logged_in">
<form action="https://metacpan.org/account/favorite/add" style="display: inline" onsubmit="return favDistribution(this)">
    <input type="hidden" name="remove" value="0">
    <input type="hidden" name="release" value="Data-Dump-Streamer-2.42">
    <input type="hidden" name="author" value="YVES">
    <input type="hidden" name="distribution" value="Data-Dump-Streamer">
    <button type="submit" class="favorite highlight"><span>10</span> ++</button>
</form>
</div>
<div class="logged_out">
<a href="./Data::Dump::Streamer.html" onclick="alert('Please sign in to add favorites'); return false" class="favorite highlight">
<span>10</span> ++</a>
</div>
   / <span>Data::Dump::Streamer</span>
</div>
          </div>
          <main class="content">


<nav class="toc">
  <div class="toc-header"><strong>Contents</strong></div>
<ul>
  <li><a href="./Data::Dump::Streamer.html#NAME">NAME</a></li>
  <li><a href="./Data::Dump::Streamer.html#SYNOPSIS">SYNOPSIS</a></li>
  <li><a href="./Data::Dump::Streamer.html#DESCRIPTION">DESCRIPTION</a>
    <ul>
      <li><a href="./Data::Dump::Streamer.html#Caveats-Dumping-Closures-(CODE-Refs)">Caveats Dumping Closures (CODE Refs)</a></li>
    </ul>
  </li>
  <li><a href="./Data::Dump::Streamer.html#USAGE">USAGE</a>
    <ul>
      <li><a href="./Data::Dump::Streamer.html#Controlling-Object-Representation">Controlling Object Representation</a></li>
      <li><a href="./Data::Dump::Streamer.html#Controlling-Hash-Traversal-and-Display-Order">Controlling Hash Traversal and Display Order</a></li>
      <li><a href="./Data::Dump::Streamer.html#Controlling-Array-Presentation-and-Run-Length-Encoding">Controlling Array Presentation and Run Length Encoding</a></li>
      <li><a href="./Data::Dump::Streamer.html#Installing-DDS-as-a-package-alias">Installing DDS as a package alias</a></li>
      <li><a href="./Data::Dump::Streamer.html#use-time-package-aliasing">use-time package aliasing</a></li>
      <li><a href="./Data::Dump::Streamer.html#PadWalker-support">PadWalker support</a></li>
    </ul>
  </li>
  <li><a href="./Data::Dump::Streamer.html#INTERFACE">INTERFACE</a>
    <ul>
      <li><a href="./Data::Dump::Streamer.html#Data::Dumper-Compatibility">Data::Dumper Compatibility</a></li>
      <li><a href="./Data::Dump::Streamer.html#Constructors">Constructors</a></li>
      <li><a href="./Data::Dump::Streamer.html#Methods">Methods</a></li>
      <li><a href="./Data::Dump::Streamer.html#Reading-the-Output">Reading the Output</a></li>
      <li><a href="./Data::Dump::Streamer.html#A-Note-About-Speed">A Note About Speed</a></li>
    </ul>
  </li>
  <li><a href="./Data::Dump::Streamer.html#EXPORT">EXPORT</a></li>
  <li><a href="./Data::Dump::Streamer.html#BUGS">BUGS</a></li>
  <li><a href="./Data::Dump::Streamer.html#AUTHOR-AND-COPYRIGHT">AUTHOR AND COPYRIGHT</a></li>
  <li><a href="./Data::Dump::Streamer.html#SEE-ALSO-(its-a-crowded-space,-isn&#39;t-it!)">SEE ALSO (its a crowded space, isn&#39;t it!)</a></li>
</ul></nav>
<div class="pod anchors">
<h1 id="NAME">NAME</h1>

<p>Data::Dump::Streamer - Accurately serialize a data structure as Perl code.</p>

<h1 id="SYNOPSIS">SYNOPSIS</h1>

<pre><code>  use Data::Dump::Streamer;
  use DDS;                           # optionally installed alias

  Dump($x,$y);                       # Prints to STDOUT
  Dump($x,$y)-&gt;Out();                #   &quot;          &quot;

  my $o=Data::Dump::Streamer-&gt;new(); # Returns a new ...
  my $o=Dump();                      # ... uninitialized object.

  my $o=Dump($x,$y);                 # Returns an initialized object
  my $s=Dump($x,$y)-&gt;Out();          #  &quot;  a string of the dumped obj
  my @l=Dump($x,$y);                 #  &quot;  a list of code fragments
  my @l=Dump($x,$y)-&gt;Out();          #  &quot;  a list of code fragments

  Dump($x,$y)-&gt;To(\*STDERR)-&gt;Out();  # Prints to STDERR

  Dump($x,$y)-&gt;Names(&#39;foo&#39;,&#39;bar&#39;)    # Specify Names
             -&gt;Out();

  Dump($x,$y)-&gt;Indent(0)-&gt;Out();     # No indent

  Dump($x,$y)-&gt;To(\*STDERR)          # Output to STDERR
             -&gt;Indent(0)             # ... no indent
             -&gt;Names(&#39;foo&#39;,&#39;bar&#39;)    # ... specify Names
             -&gt;Out();                # Print...

  $o-&gt;Data($x,$y);                   # OO form of what Dump($x,$y) does.
  $o-&gt;Names(&#39;Foo&#39;,&#39;Names&#39;);          #  ...
  $o-&gt;Out();                         #  ...</code></pre>

<h1 id="DESCRIPTION">DESCRIPTION</h1>

<p>Given a list of scalars or reference variables, writes out their contents in perl syntax. The references can also be objects. The contents of each variable is output using the least number of Perl statements as convenient, usually only one. Self-referential structures, closures, and objects are output correctly.</p>

<p>The return value can be evaled to get back an identical copy of the original reference structure. In some cases this may require the use of utility subs that <a href="./Data::Dump::Streamer.html">Data::Dump::Streamer</a> will optionally export.</p>

<p>This module is very similar in concept to the core module <a href="https://metacpan.org/pod/Data::Dumper">Data::Dumper</a>, with the major differences being that this module is designed to output to a stream instead of constructing its output in memory (trading speed for memory), and that the traversal over the data structure is effectively breadth first versus the depth first traversal done by the others.</p>

<p>In fact the data structure is scanned twice, first in breadth first mode to perform structural analysis, and then in depth first mode to actually produce the output, but obeying the depth relationships of the first pass.</p>

<h2 id="Caveats-Dumping-Closures-(CODE-Refs)"><a id="Caveats"></a><a id="Caveats-Dumping-Closures--CODE-Refs"></a>Caveats Dumping Closures (CODE Refs)</h2>

<p>As of version 1.11 DDS has had the ability to dump closures properly. This means that the lexicals that are bound to the closure are dumped along with the subroutine that uses them. This makes it much easier to debug code that uses closures and to a certain extent provides a persistency framework for closure based code. The way this works is that DDS figures out what all the lexicals are that are bound to CODE refs it is dumping and then pretends that it had originally been called with all of them as its arguments, (along with the original arguments as well of course.)</p>

<p>One consequence of the way the dumping process works is that all of the recreated subroutines will be in the same scope. This of course can lead to collisions as two subroutines can easily be bound to different variables that have the same name.</p>

<p>The way that DDS resolves these collisions is that it renames one of the variables with a special name so that presumably there are no collisions. However this process is very simplistic with no checks to prevent collisions with other lexicals or other globals that may be used by other dumped code. In some situations it may be necessary to change the default value of the rename template which may be done by using the <code>EclipseName</code> method.</p>

<p>Similarly to the problem of colliding lexicals is the problem of colliding lexicals and globals. DDS pays no attention to globals when dumping closures which can potentially result in lexicals being declared that will eclipse their global namesake. There is currently no way around this other than to avoid accessing a global and a lexical with the same name from the subs being dumped. An example is</p>

<pre><code>  my $a = sub { $a++ };
  Dump( sub { $a-&gt;() } );</code></pre>

<p>which will not be dumped correctly. Generally speaking this kind of thing is bad practice anyway, so this should probably be viewed as a &quot;feature&quot;. :-)</p>

<p>Generally if the closures being dumped avoid accessing lexicals and globals with the same name from out of scope and that all of the CODE being dumped avoids vars with the <code>EclipseName</code> in their names the dumps should be valid and should eval back into existence properly.</p>

<p>Note that the behaviour of dumping closures is subject to change in future versions as its possible that I will put some additional effort into more sophisticated ways of avoiding name collisions in the dump.</p>

<h1 id="USAGE">USAGE</h1>

<p>While Data::Dump::Streamer is at heart an object oriented module, it is expected (based on experience with using <a href="https://metacpan.org/pod/Data::Dumper">Data::Dumper</a>) that the common case will not exploit these features. Nevertheless the method based approach is convenient and accordingly a compromise hybrid approach has been provided via the <code>Dump()</code> subroutine. Such as</p>

<pre><code>   Dump($foo);
   $as_string= Dump($foo)-&gt;Out();</code></pre>

<p>All attribute methods are designed to be chained together. This means that when used as set attribute (called with arguments) they return the object they were called against. When used as get attributes (called without arguments) they return the value of the attribute.</p>

<p>From an OO point of view the key methods are the <code>Data()</code> and <code>Out()</code> methods. These correspond to the breadth first and depth first traversal, and need to be called in this order. Some attributes <i>must</i> be set prior to the <code>Data()</code> phase and some need only be set before the <code>Out()</code> phase.</p>

<p>Attributes once set last the lifetime of the object, unless explicitly reset.</p>

<h2 id="Controlling-Object-Representation"><a id="Controlling"></a>Controlling Object Representation</h2>

<p>This module provides hooks to allow objects to override how they are represented. The basic idea is that a subroutine (or method) is provided which is responsible for the override. The return of the method governs how the object will be represented when dumped, and how it will be restored. The basic calling convention is</p>

<pre><code>    my ( $proxy, $thaw, $postop )= $callback-&gt;($obj);
    #or                          = $obj-&gt;$method();</code></pre>

<p>The <a href="./Data::Dump::Streamer.html#Freezer"><code>Freezer()</code></a> method controls what methods to use as a default method and also allows per class overrides. When dumping an object of a given class the first time it tries to execute the class specific handler if it is specified, then the user specific generic handler if its been specified and then &quot;DDS_freeze&quot;. This means that class authors can implement a <code>DDS_freeze()</code> method and their objects will automatically be serialized as necessary. <b>Note</b> that if either the class specific or generic handler is defined but false <code>DDS_freeze()</code> will not be used even if it is present.</p>

<p>The interface of the <a href="./Data::Dump::Streamer.html#Freezer"><code>Freezer()</code></a> handler in detail is as follows:</p>

<dl>

<dt id="$obj"><a id="obj"></a><b><code>$obj</code></b></dt>
<dd>

<p>The object being dumped.</p>

</dd>
<dt id="$proxy"><a id="proxy"></a><b><code>$proxy</code></b></dt>
<dd>

<p>This is what will be dumped instead of <code>$obj</code>. It may be one of the following values:</p>

<dl>

<dt id="undef-(first-time-only)"><a id="undef"></a><a id="undef--first-time-only"></a><i><code>undef</code></i> (first time only)</dt>
<dd>

<p>On the first time a serialization hook is called in a dump it may return undef or the empty list to indicate that it shouldn&#39;t be used again for this class during this pass. Any other time undef is treated the same as false.</p>

</dd>
<dt id="FALSE-value"><a id="FALSE"></a><i>FALSE value</i></dt>
<dd>

<p>A false value for <code>$proxy</code> is taken to mean that it should be ignored. Its like saying IgnoreClass(ref($obj)); <b>Note</b> that undef has a special meaning when the callback is called the first time.</p>

</dd>
<dt id="A-Reference"><a id="A"></a><i>A Reference</i></dt>
<dd>

<p>A reference that will be dumped instead of the object.</p>

</dd>
<dt id="Perl-Code"><a id="Perl"></a><i>Perl Code</i></dt>
<dd>

<p>A string that is to be treated as code and inserted directly into the dump stream as a proxy for the original. Note that the code must be able to execute inline or in other words must evaluate to a perl EXPR. Use <code>do{}</code> to wrap multistatement code.</p>

</dd>
</dl>

</dd>
<dt id="$thaw"><a id="thaw"></a><b><code>$thaw</code></b></dt>
<dd>

<p>This values is used to allow extra control over how the object will be recreated when dumped. It is used for converting the <code>$proxy</code> representation into the real thing. It is only relevant when <code>$proxy</code> is a reference.</p>

<dl>

<dt id="FALSE-value1"><a id="FALSE1"></a><i>FALSE value</i></dt>
<dd>

<p>Indicates no thaw action is to be included for this object.</p>

</dd>
<dt id="Sub-or-Method-Name"><a id="Sub"></a><i>Sub or Method Name</i></dt>
<dd>

<p>A string matching <code>/^(-&gt;)?((?:\w*::)\w+)(\(\))?$/</code> in which case it is taken as a sub name when the string ends in () and a method name when the string doesn&#39;t. If the <code>-&gt;</code> is present then the sub or method is called inline. If it is not then the sub or method is called after the main dump.</p>

</dd>
<dt id="Perl-Code1"><a id="Perl1"></a><i>Perl Code</i></dt>
<dd>

<p>Any other string, in which case the result will be taken as code which will be emitted after the main dump. It will be wrapped in a for loop that aliases <code>$_</code> to the variable in question.</p>

</dd>
</dl>

</dd>
<dt id="$postdump"><a id="postdump"></a><b><code>$postdump</code></b></dt>
<dd>

<p>This is the similar to <code>$thaw</code> but is called in process instead of being emitted as part of the dump. Any return is ignored. It is only relevant when <code>$proxy</code> is a reference.</p>

<dl>

<dt id="FALSE-value2"><a id="FALSE2"></a><i>FALSE value</i></dt>
<dd>

<p>No postdump action is to occur.</p>

</dd>
<dt id="Code-Reference"><a id="Code"></a><i>Code Reference</i></dt>
<dd>

<p>The code ref will be called after serialization is complete with the object as the argument.</p>

</dd>
<dt id="Method-Name"><a id="Method"></a><i>Method Name</i></dt>
<dd>

<p>The method will be called after serialization is complete</p>

</dd>
</dl>

</dd>
</dl>

<p>An example DDS_freeze method is one I had to put together for an object which contained a key whose value was a ref to an array tied to the value of another key. Dumping this got crazy, so I wanted to suppress dumping the tied array. I did it this way:</p>

<pre><code>    sub DDS_freeze {
        my $self=shift;
        delete $self-&gt;{&#39;tie&#39;};
        return ($self,&#39;-&gt;fix_tie&#39;,&#39;fix_tie&#39;);
    }

    sub fix_tie {
        my $self=shift;
        if ( ! $self-&gt;{&#39;tie&#39;} ) {
            $self-&gt;{str}=&quot;&quot; unless defined $self-&gt;{str};
            tie my @a, &#39;Tie::Array::PackedC&#39;, $self-&gt;{str};
            $self-&gt;{&#39;tie&#39;} = \@a;
        }
        return $self;
    }</code></pre>

<p>The <code>$postop</code> means the object is relatively unaffected after the dump, the <code>$thaw</code> says that we should also include the method inline as we dump. An example dump of an object like this might be</p>

<pre><code>   $Foo1=bless({ str=&gt;&#39;&#39; },&#39;Foo&#39;)-&gt;fix_tie();</code></pre>

<p>Wheras if we omit the <code>-&gt;</code> then we would get:</p>

<pre><code>    $Foo1=bless({ str=&gt;&#39;&#39; },&#39;Foo&#39;);
    $Foo1-&gt;fix_tie();</code></pre>

<p>In our example it wouldn&#39;t actually make a difference, but the former style can be nicer to read if the object is embedded in another. However the non arrow notation is slightly more dangerous, in that its possible that the internals of the object will not be fully linked when the method is evaluated. The second form guarantees that the object will be fully linked when the method is evaluated.</p>

<p>See <a href="./Data::Dump::Streamer.html#Controlling-Hash-Traversal-and-Display-Order">&quot;Controlling Hash Traversal and Display Order&quot;</a> for a different way to control the representation of hash based objects.</p>

<h2 id="Controlling-Hash-Traversal-and-Display-Order"><a id="Controlling1"></a>Controlling Hash Traversal and Display Order</h2>

<p>When dumping a hash you may control the order the keys will be output and which keys will be included. The basic idea is to specify a subroutine which takes a hash as an argument and returns a reference to an array containing the keys to be dumped.</p>

<p>You can use the <a href="./Data::Dump::Streamer.html#KeyOrder-TYPE_OR_OBJ">KeyOrder()</a> routine or the <a href="./Data::Dump::Streamer.html#SortKeys">SortKeys()</a> routine to specify the sorter to be used.</p>

<p>The routine will be called in the following way:</p>

<pre><code>   ( $key_array, $thaw ) = $sorter-&gt;($hash,($pass=0),$addr,$class);
   ( $key_array,)        = $sorter-&gt;($hash,($pass=1),$addr,$class);</code></pre>

<p><code>$hash</code> is the hash to be dumped, <code>$addr</code> is the refaddr() of the <code>$hash</code>, and <code>$class</code> will be set if the hash has been blessed.</p>

<p>When <code>$pass</code> is 0 the <code>$thaw</code> variable may be supplied as well as the keyorder. If it is defined then it specifies what thaw action to perform after dumping the hash. See <a href="./Data::Dump::Streamer.html#$thaw"><code>$thaw</code></a> in <a href="./Data::Dump::Streamer.html#Controlling-Object-Representation">&quot;Controlling Object Representation&quot;</a> for details as to how it works. This allows an object to define those keys needed to recreate itself properly, and a followup hook to recreate the rest.</p>

<p><b>Note</b> that if a <a href="./Data::Dump::Streamer.html#Freezer">Freezer()</a> method is defined and returns a <a href="./Data::Dump::Streamer.html#$thaw"><code>$thaw</code></a> then the <a href="./Data::Dump::Streamer.html#$thaw"><code>$thaw</code></a> returned by the sorter will override it.</p>

<h2 id="Controlling-Array-Presentation-and-Run-Length-Encoding"><a id="Controlling2"></a>Controlling Array Presentation and Run Length Encoding</h2>

<p>By default Data::Dump::Streamer will &quot;run length encode&quot; array values. This means that when an array value is simple (ie, its not referenced and does contain a reference) and is repeated multiple times the output will be single a list multiplier statement, and not each item output separately. Thus: <a href="./Data::Dump::Streamer.html#Dump"><code>Dump([0,0,0,0])</code></a> will be output something like</p>

<pre><code>   $ARRAY1 = [ (0) x 4 ];</code></pre>

<p>This is particularly useful when dealing with large arrays that are only partly filled, and when accidentally the array has been made very large, such as with the improper use of pseudo-hash notation.</p>

<p>To disable this feature you may set the <a href="./Data::Dump::Streamer.html#Rle">Rle()</a> property to FALSE, by default it is enabled and set to TRUE.</p>

<h2 id="Installing-DDS-as-a-package-alias"><a id="Installing"></a>Installing <i>DDS</i> as a package alias</h2>

<p>Its possible to have an alias to Data::Dump::Streamer created and installed for easier usage in one liners and short scripts. Data::Dump::Streamer is a bit long to type sometimes. However because this technically means polluting the root level namespace, and having it listed on CPAN, I have elected to have the installer not install it by default. If you wish it to be installed you must explicitly state so when Build.Pl is run:</p>

<pre><code>  perl Build.Pl DDS [Other Module::Build options]</code></pre>

<p>Then a normal &#39;./Build test, ./Build install&#39; invocation will install DDS.</p>

<p>Using DDS is identical to Data::Dump::Streamer.</p>

<h2 id="use-time-package-aliasing"><a id="use"></a>use-time package aliasing</h2>

<p>You can also specify an alias at use-time, then use that alias in the rest of your program, thus avoiding the permanent (but modest) namespace pollution of the previous method.</p>

<pre><code>  use Data::Dumper::Streamer as =&gt; &#39;DDS&#39;;

  # or if you prefer
  use Data::Dumper::Streamer;
  import Data::Dumper::Streamer as =&gt; &#39;DDS&#39;;</code></pre>

<p>You can use any alias you like, but that doesn&#39;t mean you should.. Folks doing as =&gt; &#39;DBI&#39; will be mercilessly ridiculed.</p>

<h2 id="PadWalker-support"><a id="PadWalker"></a>PadWalker support</h2>

<p>If PadWalker 1.0 is installed you can use DumpLex() to try to automatically determine the names of the vars being dumped. As long as the vars being dumped have my or our declarations in scope the vars will be correctly named. Padwalker will also be used instead of the B:: modules when dumping closures when it is available.</p>

<h1 id="INTERFACE">INTERFACE</h1>

<h2 id="Data::Dumper-Compatibility"><a id="Data"></a>Data::Dumper Compatibility</h2>

<p>For drop in compatibility with the Dumper() usage of Data::Dumper, you may request that the <a href="./Data::Dump::Streamer.html#Dumper">Dumper()</a> method is exported. It will not be exported by default. In addition the standard Data::Dumper::Dumper() may be exported on request as <code>DDumper</code>. If you provide the tag <code>:Dumper</code> then both will be exported.</p>

<dl>

<dt id="Dumper">Dumper</dt>
<dd>

</dd>
<dt id="Dumper-LIST"><a id="Dumper1"></a>Dumper LIST</dt>
<dd>

<p>A synonym for scalar Dump(LIST)-&gt;Out for usage compatibility with <a href="https://metacpan.org/pod/Data::Dumper">Data::Dumper</a></p>

</dd>
<dt id="DDumper">DDumper</dt>
<dd>

</dd>
<dt id="DDumper-LIST"><a id="DDumper1"></a>DDumper LIST</dt>
<dd>

<p>A secondary export of the actual <a href="https://metacpan.org/pod/Data::Dumper">Data::Dumper::Dumper</a> subroutine.</p>

</dd>
</dl>

<h2 id="Constructors">Constructors</h2>

<dl>

<dt id="new">new</dt>
<dd>

<p>Creates a new Data::Dump::Streamer object. Currently takes no arguments and simply returns the new object with a default style configuration.</p>

<p>See <code>Dump()</code> for a better way to do things.</p>

</dd>
<dt id="Dump">Dump</dt>
<dd>

</dd>
<dt id="Dump-VALUES"><a id="Dump1"></a>Dump VALUES</dt>
<dd>

<p>Smart non method based constructor.</p>

<p>This routine behaves very differently depending on the context it is called in and whether arguments are provided.</p>

<p>If called with no arguments it is exactly equivalent to calling</p>

<pre><code>  Data::Dump::Streamer-&gt;new()</code></pre>

<p>which means it returns an object reference.</p>

<p>If called with arguments and in scalar context it is equivalent to calling</p>

<pre><code>  Data::Dump::Streamer-&gt;new()-&gt;Data(@vals)</code></pre>

<p>except that the actual depth first traversal is <i>delayed</i> until <code>Out()</code> is called. This means that options that must be provided before the <code>Data()</code> phase can be provided after the call to <code>Dump()</code>. Again, it returns a object reference.</p>

<p>If called with arguments and in void or list context it is equivelent to calling</p>

<pre><code>  Data::Dump::Streamer-&gt;new()-&gt;Data(@vals)-&gt;Out()</code></pre>

<p>The reason this is true in list context is to make <code>print Dump(...),&quot;\n&quot;;</code> do the right thing. And also that combined with method chaining options can be added or removed as required quite easily and naturally.</p>

<p>So to put it short:</p>

<pre><code>  my $obj=Dump($x,$y);         # Returns an object
  my $str=Dump($x,$y)-&gt;Out();  # Returns a string of the dump.
  my @code=Dump($x,$y);        # Returns a list of the dump.

  Dump($x,$y);                 # prints the dump.
  print Dump($x,$y);           # prints the dump.</code></pre>

<p>It should be noted that the setting of <code>$\</code> will affect the behaviour of both of</p>

<pre><code>  Dump($x,$y);
  print Dump($x,$y);</code></pre>

<p>but it will not affect the behaviour of</p>

<pre><code>  print scalar Dump($x,$y);</code></pre>

<p><b>Note</b> As of 1.11 Dump also works as a method, with identical properties as when called as a subroutine, with the exception that when called with no arguments it is a synonym for <code>Out()</code>. Thus</p>

<pre><code>  $obj-&gt;Dump($foo)-&gt;Names(&#39;foo&#39;)-&gt;Out();</code></pre>

<p>will work fine, as will the odd looking:</p>

<pre><code>  $obj-&gt;Dump($foo)-&gt;Names(&#39;foo&#39;)-&gt;Dump();</code></pre>

<p>which are both the same as</p>

<pre><code>  $obj-&gt;Names(&#39;foo&#39;)-&gt;Data($foo)-&gt;Out();</code></pre>

<p>Hopefully this should make method use more or less DWIM.</p>

</dd>
<dt id="DumpLex-VALUES"><a id="DumpLex"></a>DumpLex VALUES</dt>
<dd>

<p>DumpLex is similar to Dump except it will try to automatically determine the names to use for the variables being dumped by using PadWalker to have a poke around the calling lexical scope to see what is declared. If a name for a var can&#39;t be found then it will be named according to the normal scheme. When PadWalker isn&#39;t installed this is just a wrapper for <a href="./Data::Dump::Streamer.html#Dump">Dump()</a>.</p>

<p>Thanks to Ovid for the idea of this. See <a href="https://metacpan.org/pod/Data::Dumper::Simple">Data::Dumper::Simple</a> for a similar wrapper around <a href="https://metacpan.org/pod/Data::Dumper">Data::Dumper</a>.</p>

</dd>
<dt id="DumpVars-PAIRS"><a id="DumpVars"></a>DumpVars PAIRS</dt>
<dd>

<p>This is wrapper around <a href="./Data::Dump::Streamer.html#Dump">Dump()</a> which expect to receive a list of name=&gt;value pairs instead of a list of values. Otherwise behaves like <a href="./Data::Dump::Streamer.html#Dump">Dump()</a>. Note that names starting with a &#39;-&#39; are treated the same as those starting with &#39;*&#39; when passed to <a href="./Data::Dump::Streamer.html#Names">Names()</a>.</p>

</dd>
</dl>

<h2 id="Methods">Methods</h2>

<dl>

<dt id="Data1">Data</dt>
<dd>

</dd>
<dt id="Data-LIST"><a id="Data2"></a>Data LIST</dt>
<dd>

<p>Analyzes a list of variables in breadth first order.</p>

<p>If called with arguments then the internal object state is reset before scanning the list of arguments provided.</p>

<p>If called with no arguments then whatever arguments were provided to <code>Dump()</code> will be scanned.</p>

<p>Returns $self.</p>

</dd>
<dt id="Out">Out</dt>
<dd>

</dd>
<dt id="Out-VALUES"><a id="Out1"></a>Out VALUES</dt>
<dd>

<p>Prints out a set of values to the appropriate location. If provided a list of values then the values are first scanned with <code>Data()</code> and then printed, if called with no values then whatever was scanned last with <code>Data()</code> or <code>Dump()</code> is printed.</p>

<p>If the <code>To()</code> attribute was provided then will dump to whatever object was specified there (any object, including filehandles that accept the print() method), and will always return $self.</p>

<p>If the <code>To()</code> attribute was not provided then will use an internal printing object, returning either a list or scalar or printing to STDOUT in void context.</p>

<p>This routine is virtually always called without arguments as the last method in the method chain.</p>

<pre><code> Dump-&gt;Arguments(1)-&gt;Out(@vars);
 $obj-&gt;Data(@vars)-&gt;Out();
 Dump(@vars)-&gt;Out;
 Data::Dump::Streamer-&gt;Out(@vars);</code></pre>

<p>All should DWIM.</p>

</dd>
<dt id="Names">Names</dt>
<dd>

</dd>
<dt id="Names-LIST"><a id="Names1"></a>Names LIST</dt>
<dd>

</dd>
<dt id="Names-ARRAYREF"><a id="Names2"></a>Names ARRAYREF</dt>
<dd>

<p>Takes a list of strings or a reference to an array of strings to use for var names for the objects dumped. The names may be prefixed by a * indicating the variable is to be dumped as its dereferenced type if it is an array, hash or code ref. Otherwise the star is ignored. Other sigils may be prefixed but they will be silently converted to *&#39;s.</p>

<p>If no names are provided then names are generated automatically based on the type of object being dumped, with abbreviations applied to compound class names.</p>

<p>If called with arguments then returns the object itself, otherwise in list context returns the list of names in use, or in scalar context a reference or undef. In void context with no arguments the names are cleared.</p>

<p><b>NOTE:</b> Must be called before <code>Data()</code> is called.</p>

<p>If you wish to have no names, use <a href="https://metacpan.org/pod/Terse">Terse</a>.</p>

</dd>
<dt id="Terse">Terse</dt>
<dd>

</dd>
<dt id="Terse-BOOL"><a id="Terse1"></a>Terse BOOL</dt>
<dd>

<p>When true, no variable names will be created. Data will be dumped as anonymous references or values.</p>

<pre><code>    Dump([])-&gt;Out;              # $ARRAY1 = []
    Dump([])-&gt;Terse(1)-&gt;Out;    # []</code></pre>

</dd>
<dt id="Purity">Purity</dt>
<dd>

</dd>
<dt id="Purity-BOOL"><a id="Purity1"></a>Purity BOOL</dt>
<dd>

<p>This option can be used to set the level of purity in the output. It defaults to TRUE, which results in the module doing its best to ensure that the resulting dump when eval()ed is precisely the same as the input. However, at times such as debugging this can be tedious, resulting in extremely long dumps with many &quot;fix&quot; statements involved. By setting Purity to FALSE the resulting output won&#39;t necessarily be legal Perl, but it will be more legible. In this mode the output is broadly similar to that of the default setting of Data::Dumper (Purity(0)). When set to TRUE the behaviour is likewise similar to Data::Dumper in Purity(1) but more accurate.</p>

<p>When Purity() is set to FALSE aliases will be output with a function call wrapper of &#39;alias_to&#39; whose argument will be the value the item is an alias to. This wrapper does nothing, and is only there as a visual cue. Likewise, &#39;make_ro&#39; will be output when the value was readonly, and again the effect is cosmetic only.</p>

</dd>
<dt id="To">To</dt>
<dd>

</dd>
<dt id="To-STREAMER"><a id="To1"></a>To STREAMER</dt>
<dd>

<p>Specifies the object to print to. Data::Dump::Streamer can stream its output to any object supporting the print method. This is primarily meant for streaming to a filehandle, however any object that supports the method will do.</p>

<p>If a filehandle is specified then it is used until it is explicitly changed, or the object is destroyed.</p>

</dd>
<dt id="Declare">Declare</dt>
<dd>

</dd>
<dt id="Declare-BOOL"><a id="Declare1"></a>Declare BOOL</dt>
<dd>

<p>If Declare is True then each object is dumped with &#39;my&#39; declarations included, and all rules that follow are obeyed. (Ie, not referencing an undeclared variable). If Declare is False then all objects are expected to be previously defined and references to top level objects can be made at any time.</p>

<p>Defaults to False.</p>

</dd>
<dt id="Indent">Indent</dt>
<dd>

</dd>
<dt id="Indent-INT"><a id="Indent1"></a>Indent INT</dt>
<dd>

<p>If Indent is True then data is output in an indented and fairly neat fashion. If the value is 2 then hash key/value pairs and array values each on their own line. If the value is 1 then a &quot;smart&quot; indenting mode is activated where multiple key/value or values may be printed to the same line. The heuristics for this mode are still experimental so it may occasional not indent very nicely.</p>

<p>Default is Indent(2)</p>

<p>If indent is False then no indentation is done, and all optional whitespace. is omitted. See &lt;OptSpace()|/OptSpace&gt; for more details.</p>

<p>Defaults to True.</p>

<p>Newlines are appended to each statement regardless of this value.</p>

</dd>
<dt id="Indentkeys">Indentkeys</dt>
<dd>

</dd>
<dt id="Indentkeys-BOOL"><a id="Indentkeys1"></a>Indentkeys BOOL</dt>
<dd>

<p>If Indent() and Indentkeys are True then hashes with more than one key value pair are dumped such that the keys and values line up. Note however this means each key has to be quoted twice. Not advised for very large data structures. Additional logic may enhance this feature soon.</p>

<p>Defaults to True.</p>

<p><b>NOTE:</b> Must be set before <code>Data()</code> is called.</p>

</dd>
<dt id="OptSpace">OptSpace</dt>
<dd>

</dd>
<dt id="OptSpace-STR"><a id="OptSpace1"></a>OptSpace STR</dt>
<dd>

<p>Normally DDS emits a lot of whitespace in between tokens that it emits. Using this method you can control how much whitespace it will emit, or even if some other string should be used.</p>

<p>If Indent is set to 0 then this value is automatically set to the empty string. When Indent is set back to a non zero value the old value will be restored if it has not been changed from the empty string in the intervening time.</p>

</dd>
<dt id="KeyOrder-TYPE_OR_OBJ"><a id="KeyOrder"></a>KeyOrder TYPE_OR_OBJ</dt>
<dd>

</dd>
<dt id="KeyOrder-TYPE_OR_OBJ,-VALUE"><a id="KeyOrder1"></a><a id="KeyOrder-TYPE_OR_OBJ--VALUE"></a>KeyOrder TYPE_OR_OBJ, VALUE</dt>
<dd>

<p>Sets or returns the key order to for use for a given type or object.</p>

<p>TYPE_OR_OBJ may be a string representing a class, or &quot;&quot; for representing unblessed objects, or it maybe a reference to a hash.</p>

<p>VALUE may be a string representing one of built in sort mechanisms, or it may be a reference to a subroutine, or a method name if TYPE_OR_OBJ is not an object.</p>

<p>The built in sort mechanisms are &#39;aphabetical&#39;/&#39;lexical&#39;, &#39;numeric&#39;, &#39;smart&#39;/&#39;intelligent&#39; and &#39;each&#39;.</p>

<p>If VALUE is omitted returns the current value for the given type.</p>

<p>If TYPE_OR_OBJ is omitted or FALSE it defaults to &quot;&quot; which represents unblessed hashes.</p>

<p>See <a href="./Data::Dump::Streamer.html#Controlling-Hash-Traversal-and-Display-Order">&quot;Controlling Hash Traversal and Display Order&quot;</a> for more details.</p>

</dd>
<dt id="SortKeys">SortKeys</dt>
<dd>

</dd>
<dt id="SortKeys-VALUE"><a id="SortKeys1"></a>SortKeys VALUE</dt>
<dd>

<p>This is a wrapper for KeyOrder. It allows only the generic hash sort order to be specified a little more elegantly than via KeyOrder(). It is syntactically equivalent to</p>

<pre><code>  $self-&gt;KeyOrder( &quot;&quot;, @_ );</code></pre>

</dd>
<dt id="Verbose">Verbose</dt>
<dd>

</dd>
<dt id="Verbose-BOOL"><a id="Verbose1"></a>Verbose BOOL</dt>
<dd>

<p>If Verbose is True then when references that cannot be resolved in a single statement are encountered the reference is substituted for a descriptive tag saying what type of forward reference it is, and to what is being referenced. The type is provided through a prefix, &quot;R:&quot; for reference, and &quot;A:&quot; for alias, &quot;V:&quot; for a value and then the name of the var in a string. Automatically generated var names are also reduced to the shortest possible unique abbreviation, with some tricks thrown in for Long::Class::Names::Like::This (which would abbreviate most likely to LCNLT1)</p>

<p>If Verbose if False then a simple placeholder saying &#39;A&#39; or &#39;R&#39; is provided. (In most situations perl requires a placeholder, and as such one is always provided, even if technically it could be omitted.)</p>

<p>This setting does not change the followup statements that fix up the structure, and does not result in a loss of accuracy, it just makes it a little harder to read. OTOH, it means dumps can be quite a bit smaller and less noisy.</p>

<p>Defaults to True.</p>

<p><b>NOTE:</b> Must be set before <code>Data()</code> is called.</p>

</dd>
<dt id="DumpGlob">DumpGlob</dt>
<dd>

</dd>
<dt id="DumpGlob-BOOL"><a id="DumpGlob1"></a>DumpGlob BOOL</dt>
<dd>

<p>If True then globs will be followed and fully defined, otherwise the globs will still be referenced but their current value will not be set.</p>

<p>Defaults to True</p>

<p><b>NOTE:</b> Must be set before <code>Data()</code> is called.</p>

</dd>
<dt id="Deparse">Deparse</dt>
<dd>

</dd>
<dt id="Deparse-BOOL"><a id="Deparse1"></a>Deparse BOOL</dt>
<dd>

<p>If True then CODE refs will be deparsed use <a href="https://metacpan.org/pod/B::Deparse">B::Deparse</a> and included in the dump. If it is False the a stub subroutine reference will be output as per the setting of <code>CodeStub()</code>.</p>

<p>Caveat Emptor, dumping subroutine references is hardly a secure act, and it is provided here only for convenience.</p>

<p>Note using this routine is at your own risk as of DDS 1.11, how it interacts with the newer advanced closure dumping process is undefined.</p>

</dd>
<dt id="EclipseName">EclipseName</dt>
<dd>

</dd>
<dt id="EclipseName-SPRINTF_FORMAT"><a id="EclipseName1"></a>EclipseName SPRINTF_FORMAT</dt>
<dd>

<p>When necessary DDS will rename vars output during deparsing with this value. It is a sprintf format string that should contain only and both of the &quot;%s&quot; and a &quot;%d&quot; formats in any order along with whatever other literal text you want in the name. No checks are performed on the validity of this value so be careful. It defaults to</p>

<pre><code>  &quot;%s_eclipse_%d&quot;</code></pre>

<p>where the &quot;%s&quot; represents the name of the var being eclipsed, and the &quot;%d&quot; a counter to ensure all such mappings are unique.</p>

</dd>
<dt id="DeparseOpts">DeparseOpts</dt>
<dd>

</dd>
<dt id="DeparseOpts-LIST"><a id="DeparseOpts1"></a>DeparseOpts LIST</dt>
<dd>

</dd>
<dt id="DeparseOpts-ARRAY"><a id="DeparseOpts2"></a>DeparseOpts ARRAY</dt>
<dd>

<p>If Deparse is True then these options will be passed to B::Deparse-&gt;new() when dumping a CODE ref. If passed a list of scalars the list is used as the arguments. If passed an array reference then this array is assumed to contain a list of arguments. If no arguments are provided returns a an array ref of arguments in scalar context, and a list of arguments in list context.</p>

<p>Note using this routine is at your own risk as of DDS 1.11, how it interacts with the newer advanced closure dumping process is undefined.</p>

</dd>
<dt id="CodeStub">CodeStub</dt>
<dd>

</dd>
<dt id="CodeStub-STRING"><a id="CodeStub1"></a>CodeStub STRING</dt>
<dd>

<p>If Deparse is False then this string will be used in place of CODE references. Its the users responsibility to make sure its compilable and blessable.</p>

<p>Defaults to &#39;sub { Carp::confess &quot;Dumped code stub!&quot; }&#39;</p>

</dd>
<dt id="FormatStub">FormatStub</dt>
<dd>

</dd>
<dt id="FormatStub-STRING"><a id="FormatStub1"></a>FormatStub STRING</dt>
<dd>

<p>If Deparse is False then this string will be used in place of FORMAT references. Its the users responsibility to make sure its compilable and blessable.</p>

<p>Defaults to &#39;do{ local *F; eval &quot;format F =\nFormat Stub\n.\n&quot;; *F{FORMAT} }&#39;</p>

</dd>
<dt id="DeparseGlob">DeparseGlob</dt>
<dd>

</dd>
<dt id="DeparseGlob-BOOL"><a id="DeparseGlob1"></a>DeparseGlob BOOL</dt>
<dd>

<p>If Deparse is TRUE then this style attribute will determine if subroutines and FORMAT&#39;s contained in globs that are dumped will be deparsed or not.</p>

<p>Defaults to True.</p>

</dd>
<dt id="Dualvars">Dualvars</dt>
<dd>

</dd>
<dt id="Dualvars-BOOL"><a id="Dualvars1"></a>Dualvars BOOL</dt>
<dd>

</dd>
<dt id="Dualvars2">Dualvars</dt>
<dd>

</dd>
<dt id="Dualvars-BOOL1"><a id="Dualvars3"></a>Dualvars BOOL</dt>
<dd>

<p>If TRUE then dualvar checking will occur and the required statements emitted to recreate dualvars when they are encountered, otherwise items will be dumped in their stringified form always. It defaults to TRUE.</p>

</dd>
<dt id="Rle">Rle</dt>
<dd>

</dd>
<dt id="Rle-BOOL"><a id="Rle1"></a>Rle BOOL</dt>
<dd>

</dd>
<dt id="RLE">RLE</dt>
<dd>

</dd>
<dt id="RLE-BOOL"><a id="RLE1"></a>RLE BOOL</dt>
<dd>

<p>If True then arrays will be run length encoded using the <code>x</code> operator. What this means is that if an array contains repeated elements then instead of outputting each and every one a list multiplier will be output. This means that considerably less space is taken to dump redundant data.</p>

</dd>
<dt id="Freezer">Freezer</dt>
<dd>

</dd>
<dt id="Freezer-ACTION"><a id="Freezer1"></a>Freezer ACTION</dt>
<dd>

</dd>
<dt id="Freezer-CLASS,-ACTION"><a id="Freezer2"></a><a id="Freezer-CLASS--ACTION"></a>Freezer CLASS, ACTION</dt>
<dd>

<p>This method can be used to override the DDS_freeze hook for a specific class. If CLASS is omitted then the ACTION applies to all blessed object.</p>

<p>If ACTION is false it indicates that the given CLASS should not have any serilization hooks called.</p>

<p>If ACTION is a string then it is taken to be the method name that will be executed to freeze the object. CLASS-&gt;can(METHOD) must return true or the setting will be ignored.</p>

<p>If ACTION is a code ref it is executed with the object as the argument.</p>

<p>When called with no arguments returns in scalar context the generic serialization method (defaults to &#39;DDS_freeze&#39;), in list context returns the generic serialization method followed by a list of pairs of Classname=&gt;ACTION.</p>

<p>If the action executes a sub or method it is expected to return a list of three values:</p>

<pre><code>   ( $proxy, $thaw, $postdump )=$obj-&gt;DDS_Freeze();</code></pre>

<p>See <a href="./Data::Dump::Streamer.html#Controlling-Object-Representation">&quot;Controlling Object Representation&quot;</a> for more details.</p>

<p><b>NOTE:</b> Must be set before <code>Data()</code> is called.</p>

</dd>
<dt id="Ignore">Ignore</dt>
<dd>

</dd>
<dt id="Ignore-OBJ_OR_CLASS"><a id="Ignore1"></a>Ignore OBJ_OR_CLASS</dt>
<dd>

</dd>
<dt id="Ignore-OBJ_OR_CLASS,-BOOL"><a id="Ignore2"></a><a id="Ignore-OBJ_OR_CLASS--BOOL"></a>Ignore OBJ_OR_CLASS, BOOL</dt>
<dd>

<p>Allows a given object or class to be ignored, and replaced with a string containing the name of the item ignored.</p>

<p>If called with no args returns a list of items ignored (using the refaddr to represent objects). If called with a single argument returns whether that argument is ignored. If called with more than one arguments then expects a list of pairs of object =&gt; is_ignored.</p>

<p>Returns $self when setting.</p>

<p><b>NOTE:</b> Must be set before <code>Data()</code> is called.</p>

</dd>
<dt id="Compress">Compress</dt>
<dd>

</dd>
<dt id="Compress-SIZE"><a id="Compress1"></a>Compress SIZE</dt>
<dd>

<p>Controls compression of string values (not keys). If this value is nonzero and a string to be dumped is longer than its value then the <a href="./Data::Dump::Streamer.html#Compressor">Compressor()</a> if defined is used to compress the string. Setting size to -1 will cause all strings to be processed, setting size to 0 will cause no strings to be processed.</p>

</dd>
<dt id="Compressor">Compressor</dt>
<dd>

</dd>
<dt id="Compressor-CODE"><a id="Compressor1"></a>Compressor CODE</dt>
<dd>

<p>This attribute is used to control the compression of strings. It is expected to be a reference to a subroutine with the following interface:</p>

<pre><code>  my $prelude_code=$compressor-&gt;(); # no arguments.
  my $code=$compressor-&gt;(&#39;string&#39;); # string argument</code></pre>

<p>The sub will be called with no arguments at the beginning of the dump to allow any require statements or similar to be added. During the dump the sub will be called with a single argument when compression is required. The code returned in this case is expected to be an EXPR that will evaluate back to the original string.</p>

<p>By default DDS will use <a href="https://metacpan.org/pod/Compress::Zlib">Compress::Zlib</a> in conjunction with <a href="https://metacpan.org/pod/MIME::Base64">MIME::Base64</a> to do compression and encoding, and exposes the &#39;usqz&#39; subroutine for handling the decoding and decompression.</p>

<p>The abbreviated name was chosen as when using the default compressor every string will be represented by a string like</p>

<pre><code>   usqz(&#39;....&#39;)</code></pre>

<p>Meaning that eight characters are required without considering the data itself. Likewise Base64 was chosen because it is a representation that is high-bit safe, compact and easy to quote. Escaped strings are much less efficient for storing binary data.</p>

</dd>
</dl>

<h2 id="Reading-the-Output"><a id="Reading"></a>Reading the Output</h2>

<p>As mentioned in <a href="https://metacpan.org/pod/Verbose">Verbose</a> there is a notation used to make understanding the output easier. However at first glance it can probably be a bit confusing. Take the following example:</p>

<pre><code>    my $x=1;
    my $y=[];
    my $array=sub{\@_ }-&gt;( $x,$x,$y );
    push @$array,$y,1;
    unshift @$array,\$array-&gt;[-1];
    Dump($array);</code></pre>

<p>Which prints (without the comments of course):</p>

<pre><code>    $ARRAY1 = [
                &#39;R: $ARRAY1-&gt;[5]&#39;,        # resolved by fix 1
                1,
                &#39;A: $ARRAY1-&gt;[1]&#39;,        # resolved by fix 2
                [],
                &#39;V: $ARRAY1-&gt;[3]&#39;,        # resolved by fix 3
                1
              ];
    $ARRAY1-&gt;[0] = \$ARRAY1-&gt;[5];         # fix 1
    alias_av(@$ARRAY1, 2, $ARRAY1-&gt;[1]);  # fix 2
    $ARRAY1-&gt;[4] = $ARRAY1-&gt;[3];          # fix 3</code></pre>

<p>The first entry, <code>&#39;R: $ARRAY1-&gt;[5]&#39;</code> indicates that this slot in the array holds a reference to the currently undefined <code>$ARRAY1-&gt;[5]</code>, and as such the value will have to be provided later in what the author calls &#39;fix&#39; statements. The third entry <code>&#39;A: $ARRAY1-&gt;[1]&#39;</code> indicates that is element of the array is in fact the exact same scalar as exists in <code>$ARRAY1-&gt;[1]</code>, or is in other words, an alias to that variable. Again, this cannot be expressed in a single statement and so generates another, different, fix statement. The fifth entry <code>&#39;V: $ARRAY1-&gt;[3]&#39;</code> indicates that this slots holds a value (actually a reference value) that is identical to one elsewhere, but is currently undefined. In this case it is because the value it needs is the reference returned by the anonymous array constructor in the fourth element (<code>$ARRAY1-&gt;[3]</code>). Again this results in yet another different fix statement. If Verbose() is off then only a &#39;R&#39; &#39;A&#39; or &#39;V&#39; tag is emitted as a marker of some form is necessary.</p>

<p>All of this specialized behaviour can be bypassed by setting Purity() to FALSE, in which case the output will look very similar to what Data::Dumper outputs in low Purity setting.</p>

<p>In a later version I&#39;ll try to expand this section with more examples.</p>

<h2 id="A-Note-About-Speed"><a id="A1"></a>A Note About Speed</h2>

<p>Data::Dumper is much faster than this module for many things. However IMO it is less readable, and definitely less accurate. YMMV.</p>

<h1 id="EXPORT">EXPORT</h1>

<p>By default exports the Dump() command. Or may export on request the same command as Stream(). A Data::Dumper::Dumper compatibility routine is provided via requesting Dumper and access to the real Data::Dumper::Dumper routine is provided via DDumper. The later two are exported together with the :Dumper tag.</p>

<p>Additionally there are a set of internally used routines that are exposed. These are mostly direct copies of routines from Array::RefElem, Lexical::Alias and Scalar::Util, however some where marked have had their semantics slightly changed, returning defined but false instead of undef for negative checks, or throwing errors on failure.</p>

<p>The following XS subs (and tagnames for various groupings) are exportable on request.</p>

<pre><code>  :Dumper
        Dumper
        DDumper

  :undump          # Collection of routines needed to undump something
        alias_av              # aliases a given array value to a scalar
        alias_hv              # aliases a given hashes value to a scalar
        alias_ref             # aliases a scalar to another scalar
        make_ro               # makes a scalar read only
        lock_keys             # pass through to Hash::Util::lock_keys
        lock_keys_plus        # like lock_keys, but adds keys to those present
        lock_ref_keys         # like lock_keys but operates on a hashref
        lock_ref_keys_plus    # like lock_keys_plus but operates on a hashref
        dualvar               # make a variable with different string/numeric
                              # representation
        alias_to              # pretend to return an alias, used in low
                              # purity mode to indicate a value is actually
                              # an alias to something else.

  :alias           # all croak on failure
     alias_av(@Array,$index,$var);
     alias_hv(%hash,$key,$var);
     alias_ref(\$var1,\$var2);
     push_alias(@array,$var);

  :util
     blessed($var)           #undef or a class name.
     isweak($var)            #returns true if $var contains a weakref
     reftype($var)           #the underlying type or false but defined.
     refaddr($var)           #a references address
     refcount($var)          #the number of times a reference is referenced
     sv_refcount($var)       #the number of times a scalar is referenced.
     weak_refcount($var)     #the number of weakrefs to an object.
                             #sv_refcount($var)-weak_refcount($var) is the true
                             #SvREFCOUNT() of the var.
     looks_like_number($var) #if perl will think this is a number.

     regex($var)     # In list context returns the pattern and the modifiers,
                     # in scalar context returns the pattern in (?msix:) form.
                     # If not a regex returns false.
     readonly($var)  # returns whether the $var is readonly
     weaken($var)    # cause the reference contained in var to become weak.
     make_ro($var)   # causes $var to become readonly, returns the value of $var.
     reftype_or_glob # returns the reftype of a reference, or if its not
                     # a reference but a glob then the globs name
     refaddr_or_glob # similar to reftype_or_glob but returns an address
                     # in the case of a reference.
     globname        # returns an evalable string to represent a glob, or
                     # the empty string if not a glob.
  :all               # (Dump() and Stream() and Dumper() and DDumper()
                     #  and all of the XS)
  :bin               # (not Dump() but all of the rest of the XS)</code></pre>

<p>By default exports only Dump(), DumpLex() and DumpVars(). Tags are provided for exporting &#39;all&#39; subroutines, as well as &#39;bin&#39; (not Dump()), &#39;util&#39; (only introspection utilities) and &#39;alias&#39; for the aliasing utilities. If you need to ensure that you can eval the results (undump) then use the &#39;undump&#39; tag.</p>

<h1 id="BUGS">BUGS</h1>

<p>Code with this many debug statements is certain to have errors. :-)</p>

<p>Please report them with as much of the error output as possible.</p>

<p>Be aware that to a certain extent this module is subject to whimsies of your local perl. The same code may not produce the same dump on two different installs and versions. Luckily these don&#39;t seem to pop up often.</p>

<h1 id="AUTHOR-AND-COPYRIGHT"><a id="AUTHOR"></a>AUTHOR AND COPYRIGHT</h1>

<p>Yves Orton, yves at cpan org.</p>

<p>Copyright (C) 2003-2005 Yves Orton</p>

<p>This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.</p>

<p>Contains code derived from works by Gisle Aas, Graham Barr, Jeff Pinyan, Richard Clamp, and Gurusamy Sarathy.</p>

<p>Thanks to Dan Brook, Yitzchak Scott-Thoennes, eric256, Joshua ben Jore, Jim Cromie, Curtis &quot;Ovid&quot; Poe, Lars D&#x26A;&#x1D07;&#x1D04;&#x1D0B;&#x1D0F;&#x1D21;, and anybody that I&#39;ve forgotten for patches, feedback and ideas.</p>

<h1 id="SEE-ALSO-(its-a-crowded-space,-isn&#39;t-it!)"><a id="SEE"></a><a id="SEE-ALSO--its-a-crowded-space--isn-t-it"></a>SEE ALSO (its a crowded space, isn&#39;t it!)</h1>

<p><a href="https://metacpan.org/pod/Data::Dumper">Data::Dumper</a> - the mother of them all</p>

<p><a href="https://metacpan.org/pod/Data::Dumper::Simple">Data::Dumper::Simple</a> - Auto named vars with source filter interface.</p>

<p><a href="https://metacpan.org/pod/Data::Dumper::Names">Data::Dumper::Names</a> - Auto named vars without source filtering.</p>

<p><a href="https://metacpan.org/pod/Data::Dumper::EasyOO">Data::Dumper::EasyOO</a> - easy to use wrapper for DD</p>

<p><a href="https://metacpan.org/pod/Data::Dump">Data::Dump</a> - Has cool feature to squeeze data</p>

<p><a href="./Data::Dump::Streamer.html">Data::Dump::Streamer</a> - The best perl dumper. But I would say that. :-)</p>

<p><a href="https://metacpan.org/pod/Data::TreeDumper">Data::TreeDumper</a> - Non perl output, lots of rendering options</p>

<p>And of course <a href="https://metacpan.org/pod/www.perlmonks.org">www.perlmonks.org</a> and <a href="https://metacpan.org/pod/perl">perl</a> itself.</p></div>

<div id="metacpan_install-instructions-dialog" class="modal fade">
  <div class="modal-dialog">
    <div class="modal-content">
      <div class="modal-header">
        <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
        <h4 class="modal-title">Module Install Instructions</h4>
      </div>
      <div class="modal-body">
        <p>To install Data::Dump::Streamer, copy and paste the appropriate command in to your terminal.</p>
        <p><a href="https://metacpan.org/dist/App-cpanminus/view/bin/cpanm">cpanm</a></p>
        <pre><code>cpanm Data::Dump::Streamer</code></pre>
        <p><a href="https://metacpan.org/pod/CPAN">CPAN shell</a></p>
        <pre><code>perl -MCPAN -e shell
install Data::Dump::Streamer</code></pre>
        <p>For more information on module installation, please visit <a href="https://www.cpan.org/modules/INSTALL.html">the detailed CPAN module installation guide</a>.</p>
      </div>
      <div class="modal-footer">
        <a href="./Data::Dump::Streamer.html#" data-dismiss="modal" class="btn">Close</a>
      </div>
    </div>
  </div>
</div>
          </main>
          <div class="content-pagination">
          </div>
        </div>
        <footer class="footer">
          <div class="footer-container">
            <div class="footer-social">
              <div class="footer-link footer-logo">
                <a href="https://metacpan.org/">
                  <img src="https://metacpan.org/static/images/metacpan-logo.svg" alt="MetaCPAN" />
                </a>
              </div>
              <a class="footer-social-link" href="https://github.com/metacpan">
                <i class="fab fa-github-square"></i>
              </a>
              <a class="footer-social-link" href="https://fosstodon.org/@metacpan">
                <i class="fab fa-mastodon"></i>
              </a>
            </div>
            <div class="footer-links">
              <div class="footer-link">
                  <a href="https://metacpan.org/about">About</a>
              </div>
              <div class="footer-link">
                  <a href="https://metacpan.org/about/sponsors">Sponsor</a>
              </div>
              <div class="footer-link">
                  <a href="https://grep.metacpan.org">grep::cpan</a>
              </div>
              <div class="footer-link">
                  <a href="https://metacpan.org/recent">Recent</a>
              </div>
              <div class="footer-link">
                  <a href="https://metacpan.org/about/faq">FAQ</a>
              </div>
              <div class="footer-link">
                  <a href="https://metacpan.org/tools">Tools</a>
              </div>
              <div class="footer-link">
                  <a href="https://fastapi.metacpan.org/">API</a>
              </div>
              <div class="footer-link">
                  <a href="https://www.perl.org/">Perl.org</a>
              </div>
            </div>
            <div class="footer-sponsors">
              <a class="footer-sponsor-link" target="_blank" href="https://www.bytemark.co.uk/" rel="noopener">
                <img class="footer-sponsor-bytemark" src="https://metacpan.org/static/images/sponsors/bytemark_logo.svg" alt="Bytemark logo">
              </a>
              <a class="footer-sponsor-link" target="_blank" href="https://www.liquidweb.com/" rel="noopener">
                <img class="footer-sponsor-liquidweb" src="https://metacpan.org/static/images/sponsors/liquidweb_logo.png" alt="liquidweb logo">
              </a>
              <a class="footer-sponsor-link" target="_blank" href="https://deriv.com/careers/" rel="noopener">
                <img class="footer-sponsor-deriv" src="https://metacpan.org/static/images/sponsors/deriv.svg" alt="Deriv logo">
              </a>
              <a class="footer-sponsor-link" target="_blank" href="https://geocode.xyz" rel="noopener">
                <img class="footer-sponsor-geocode" src="https://metacpan.org/static/images/sponsors/geocodelogo.svg" alt="Geocode logo">
              </a>
              <a class="footer-sponsor-link" target="_blank" href="https://www.fastly.com/" rel="noopener">
                <img class="footer-sponsor-fastly" src="https://metacpan.org/static/images/sponsors/fastly_logo.svg" alt="Fastly logo">
              </a>
              <a class="footer-sponsor-link" target="_blank" href="https://opencagedata.com" rel="noopener">
                <img class="footer-sponsor-opencage" src="https://metacpan.org/static/images/sponsors/open-cage.svg" alt="OpenCage logo">
              </a>
            </div>
          </div>
        </footer>
        <div class="modal fade" tabindex="-1" role="dialog" id="metacpan_keyboard-shortcuts">
          <div class="modal-dialog">
            <div class="modal-content">
              <div class="modal-header">
                <button type="button" class="close" data-dismiss="modal">&times;</button>
                <h4 class="modal-title">Keyboard Shortcuts</h4>
              </div>
              <div class="modal-body row">
<div class="col-md-6">
  <table class="table keyboard-shortcuts">
    <thead>
      <tr>
        <th></th>
        <th>Global</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td class="keys">
          <kbd>s</kbd>
        </td>
        <td>Focus search bar</td>
      </tr>
      <tr>
        <td class="keys">
          <kbd>?</kbd>
        </td>
        <td>Bring up this help dialog</td>
      </tr>
    </tbody>
  </table>

  <table class="table keyboard-shortcuts">
    <thead>
      <tr>
        <th></th>
        <th>GitHub</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td class="keys">
          <kbd>g</kbd> <kbd>p</kbd>
        </td>
        <td>Go to pull requests</td>
      </tr>
      <tr>
        <td class="keys">
          <kbd>g</kbd> <kbd>i</kbd>
        </td>
        <td>go to github issues (only if github is preferred repository)</td>
      </tr>
    </tbody>
  </table>
</div>

<div class="col-md-6">
  <table class="table keyboard-shortcuts">
    <thead>
      <tr>
        <th></th>
        <th>POD</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td class="keys">
          <kbd>g</kbd> <kbd>a</kbd>
        </td>
        <td>Go to author</td>
      </tr>
      <tr>
        <td class="keys">
          <kbd>g</kbd> <kbd>c</kbd>
        </td>
        <td>Go to changes</td>
      </tr>
      <tr>
        <td class="keys">
          <kbd>g</kbd> <kbd>i</kbd>
        </td>
        <td>Go to issues</td>
      </tr>
      <tr>
        <td class="keys">
          <kbd>g</kbd> <kbd>d</kbd>
        </td>
        <td>Go to dist</td>
      </tr>
      <tr>
        <td class="keys">
          <kbd>g</kbd> <kbd>r</kbd>
        </td>
        <td>Go to repository/SCM</td>
      </tr>
      <tr>
        <td class="keys">
          <kbd>g</kbd> <kbd>s</kbd>
        </td>
        <td>Go to source</td>
      </tr>
      <tr>
        <td class="keys">
          <kbd>g</kbd> <kbd>b</kbd>
        </td>
        <td>Go to file browse</td>
      </tr>

    </tbody>
  </table>
</div>

<div class="col-md-12">
  <table class="table keyboard-shortcuts">
    <thead>
      <tr>
        <th></th>
        <th>Search terms</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td><em>module:</em> (e.g. <a href="https://metacpan.org/search?q=module%3APlugin">module:Plugin</a>)</td>
      </tr>
      <tr>
        <td><em>distribution:</em> (e.g. <a href="https://metacpan.org/search?q=distribution%3ADancer+auth">distribution:Dancer auth</a>)</td>
      </tr>
      <tr>
        <td><em>author:</em> (e.g. <a href="https://metacpan.org/search?q=author%3ASONGMU+Redis">author:SONGMU Redis</a>)</td>
      </tr>
      <tr>
        <td><em>version:</em> (e.g. <a href="https://metacpan.org/search?q=version%3A1.00">version:1.00</a>)</td>
      </tr>
    </tbody>
  </table>
</div>
              </div>
              <div class="modal-footer"></div>
            </div>
          </div>
        </div>
    </body>
</html>
